package org.jiucheng.template.grammar;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.jiucheng.template.util.Objs;

public class If implements Grammar {
    public static final String IF = "if";
    public static final String ELSEIF = "elseif";
    public static final String ELSE = "else";
    public static final String FI = "fi";
    
    //$l > $r
    //$l >= $r
    //$l < $r
    //$l <= $r
    //$l == $r
    //$l  != $r
    //$l != null
    //$l >= 0
    //$l == "test"
    //if
    private List<String> ic;
    private List<Grammar> i;
    //elseif
    private List<List<String>> efc;
    private List<List<Grammar>> ef;
    //else
    private List<Grammar> e;
    
    public If(String h) {
        ic = getListString(h);
    }
    
    //解析头文件
    private List<String> getListString(String h) {
        h = h.substring(h.indexOf("(") + 1, h.lastIndexOf(")"));
        String[] hs = h.split("\\s");
        List<String> list = new ArrayList<String>();
        list.add(hs[0]);
        list.add(hs[1]);
        list.add(hs[2]);
        return list;
    }
    
    public void addElse(Grammar g) {
        if(e != null) {
            e.add(g);
            return;
        }
        e = new ArrayList<Grammar>();
        e.add(g);
    }
    
    public void addElseifHeader(String h) {
        if(efc == null) {
            efc = new ArrayList<List<String>>();
        }
        efc.add(getListString(h));
        if(ef == null) {
            ef = new ArrayList<List<Grammar>>();
        }
        ef.add(new ArrayList<Grammar>());
    }
    
    public void addElseifG(Grammar g) {
        ef.get(ef.size() - 1).add(g);
    }
    
    public void addIf(Grammar g) {
        if(i != null) {
            i.add(g);
            return;
        }
        i = new ArrayList<Grammar>();
        i.add(g);
    }
    
    public void exec(Map<String, Object> context, StringBuilder sb) {
        //if
        if(isIf(ic, context)) {
            if(i != null) {
                for(Grammar g : i) {
                    g.exec(context, sb);
                }
            }
            return;
        }
        //elseif
        if(ef != null) {
            List<Grammar> gs;
            for(int i = 0, len = ef.size(); i < len; i++) {
                gs = ef.get(i);
                if(isIf(efc.get(i), context)) {
                    for(Grammar g : gs) {
                        g.exec(context, sb);
                    }
                    return;
                }
            }
        }
        //else
        if(e != null) {
            for(Grammar g : e) {
                g.exec(context, sb);
            }
        }
    }
    
    private boolean isIf(List<String> ifs, Map<String, Object> context) {
        String l = ifs.get(0).substring(1);
        String j = ifs.get(1);
        String r = ifs.get(2);
        Object lVal = Objs.get(context, l);
        Object rVal;
        if(r.charAt(0) == '$') {
            rVal = Objs.get(context, r.substring(1));
        }else if("null".equalsIgnoreCase(r)) {
            rVal = null;
        }else if(r.startsWith("\"") && r.endsWith("\"")) {
            rVal = r.substring(1, r.length() - 1);
        }else {
            rVal = r;
        }
        if("==".equals(j)) {
            if(lVal == null) {
                if(rVal == null) {
                    return true;
                }
            }else {
                if(rVal != null && String.valueOf(lVal).equals(String.valueOf(rVal))) {
                    return true;
                }
            }
        }else if("!=".equals(j)) {
            if(lVal == null) {
                if(rVal != null) {
                    return true;
                }
            }else {
                if(!lVal.equals(rVal)) {
                    return true;
                }
            }
        }else if(">".equals(j)) {
            if(lVal != null && rVal != null) {
                if(String.valueOf(lVal).compareTo(String.valueOf(rVal)) > 0) {
                    return true;
                }
            }
        }else if(">=".equals(j)) {
            if(String.valueOf(lVal).compareTo(String.valueOf(rVal)) >= 0) {
                return true;
            }
        }else if("<".equals(j)) {
            if(String.valueOf(lVal).compareTo(String.valueOf(rVal)) < 0) {
                return true;
            }
        }else if("<=".equals(j)) {
            if(String.valueOf(lVal).compareTo(String.valueOf(rVal)) <= 0) {
                return true;
            }
        }
        return false;
    }
}
